package caidan;

import caidan.data.CategoryData;
import caidan.data.RecommendData;
import caidan.net.AdminNetFunDialog;
import caidan.net.Command;
import caidan.net.NetFunDialog;
import caidan.res.Resource;
import jinyilw.common.app.AppConfig;
import jinyilw.common.Direction;
import jinyilw.common.file.FileTools;
import jinyilw.common.Operator;
import jinyilw.swing.ScreenTools;
import jinyilw.common.SettingTools;
import jinyilw.swing.FontTools;
import jinyilw.swing.SwingTools;
import jinyilw.swing.WindowTools;
import jinyilw.swing.rlaf.utils.RLafUtils;
import jinyilw.swing.visuals.Icomp.IRichLabel;
import jinyilw.swing.visuals.Jcomp.TransRichButton;
import jinyilw.swing.visuals.Rcomp.RButton;
import jinyilw.swing.visuals.Rcomp.RDialog;
import jinyilw.swing.visuals.Rcomp.RFileChooser;
import jinyilw.swing.visuals.Rcomp.RFrame;
import jinyilw.swing.visuals.Rcomp.ROptionPane;
import jinyilw.swing.visuals.window.HintWindow;
import jinyilw.tools.net.ClientTools;
import jinyilw.tools.net.NetConfig;
import jinyilw.tools.net.ServerTools;
import jinyilw.tools.net.UpdateTools;
import jinyilw.tools.net.dev.CommandPacket;

import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JTabbedPane;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class MainFrame extends RFrame
{
	private static final long serialVersionUID = -7491306083627247525L;
	private int chooseDay = -1, chooseMeal = -1;
	boolean clickToLager = SettingTools.getDefaultBool("clickToLager", true);
	private final TransRichButton submitButton = new TransRichButton("提交选择");
	private final TransRichButton dataButton = new TransRichButton("数据操作");
	private final TransRichButton editButton = new TransRichButton("食谱编辑");
	private final TransRichButton netButton = new TransRichButton("网络功能");
	private final TransRichButton favoriteViewButton = new TransRichButton(
			"查看菜单喜爱度");
	private final TransRichButton weekViewButton = new TransRichButton(
			"查看推荐食谱");
	private TransRichButton cancelEditButton, setChooseNumButton,
			setColumnButton;
	private final String str = "当前统计次数：";
	private int submitNum = 0;
	private final IRichLabel numLabel = new IRichLabel(str + submitNum);
	private final JTabbedPane tabbedPane = new JTabbedPane();

	private JDialog softSettingDialog;
	private AboutDialog aboutView;
	private SetNumDialog setNumDialog;
	private SetColDialog setColDialog;
	private SetMoreDialog setMoreDialog;
	// private SetNetDialog setNetDialog;
	private SetRecipeDialog setRecipeDialog;
	private JDialog netFunDialog;

	private Container container;
	private CategoryPanel[] categoryPanels;
	private JComboBox dayBox;
	private JComboBox mealBox;
	private JPopupMenu dataPopupMenu;
	private int dataPopHeight;
	private final PositionConfiger[] positionConfigers;
	private final JRadioButton lRadioButton = new JRadioButton("单击图片放大");
	private final JRadioButton cRadioButton = new JRadioButton("单击图片选择");
	private final JPanel transPanel = SwingTools.createTransBorderPane();
	private final ButtonGroup bgGroup = new ButtonGroup();
	private final JPanel southPanel = new JPanel();
	private CategoryData[] categoryDatas;
	private boolean editable;

	private ServerTools server;
	ClientTools client;
	private boolean autoUpdate = SettingTools.getDefaultBool("autoUpdate",
			true);
	private RecommendData recommendData;

	public MainFrame()
	{
		categoryDatas = MainApp.getCategoryDatas();
		recommendData = new RecommendData(categoryDatas);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		String title = MainApp.appName;
		if (NetConfig.isServer())
			title += "（管理员）";
		setTitle(title);
		setTitleHeight(36);
		setTitleColor(new Color(100, 255, 100));
		setTitleFont(FontTools.getCustomFont(24));
		setIconImage(Resource.getBufferedImage("foodLogo.png"));
		setWindowSymbol(Resource.starIcon);

		tabbedPane.setFont(FontTools.getCustomFont(18));
		categoryPanels = new CategoryPanel[categoryDatas.length];
		positionConfigers = new PositionConfiger[categoryDatas.length];
		for (int i = 0; i < categoryPanels.length; i++)
		{
			positionConfigers[i] = new PositionConfiger(MainApp.columns[i]);
			categoryPanels[i] = new CategoryPanel(this, categoryDatas[i],
					positionConfigers[i]);
		}

		String[] dayStr = {" 星期一", " 星期二", " 星期三", " 星期四", " 星期五", " 星期六",
				" 星期日"};
		String[] mealStr = {" 早餐", " 午餐", " 晚餐"};
		dayBox = new JComboBox(dayStr);
		mealBox = new JComboBox(mealStr);

		addClosingOperater(new CloseOperator());
		container = new Container();
		getContentPane().setLayout(null);
		getContentPane().add(container);
		container.setLayout(null);
		for (CategoryPanel panel : categoryPanels)
			container.add(panel);

		southPanel.setLayout(null);
		container.add(southPanel);
		southPanel.add(transPanel);

		ActionListener actionListener = new RadioButtonActionListener();
		lRadioButton.addActionListener(actionListener);
		lRadioButton.setFont(FontTools.getCustomFont(15));

		southPanel.add(lRadioButton);
		cRadioButton.addActionListener(actionListener);
		cRadioButton.setFont(FontTools.getCustomFont(15));
		southPanel.add(cRadioButton);
		if (clickToLager)
			lRadioButton.setSelected(true);
		else
			cRadioButton.setSelected(true);
		bgGroup.add(lRadioButton);
		bgGroup.add(cRadioButton);

		dayBox.addActionListener(new DayBoxActionListener());
		dayBox.setFont(FontTools.getCustomFont(19));
		southPanel.add(dayBox);
		mealBox.addActionListener(new MealBoxActionListener());
		mealBox.setFont(FontTools.getCustomFont(19));
		container.add(mealBox);

		submitButton.setForeground(new Color(255, 80, 80));
		submitButton.setFont(FontTools.getCustomFont(23));
		southPanel.add(submitButton);
		submitButton.addActionListener(new SubmitActionListener());
		submitButton.setImage(Resource.checkIcon);
		// submitAction.setImageDirection(SwingConstants.EAST);

		Font buttonFont = FontTools.getCustomFont(20);
		dataButton.setForeground(Color.green);
		dataButton.setFont(buttonFont);
		southPanel.add(dataButton);
		dataButton.addActionListener(new DataActionListener());
		dataButton.setImage(Resource.chartIcon);

		editButton.setForeground(Color.green);
		editButton.setFont(buttonFont);
		southPanel.add(editButton);
		editButton.addActionListener(new EditActionListener());
		editButton.setImage(Resource.editIcon);

		netButton.setForeground(Color.green);
		netButton.setFont(buttonFont);
		southPanel.add(netButton);
		netButton.addActionListener(new NetButtonListener());
		netButton.setImage(Resource.netIcon);

		weekViewButton.setForeground(Color.CYAN);
		weekViewButton.setFont(buttonFont);
		southPanel.add(weekViewButton);
		weekViewButton.addClickOperater(new WeekActionOperator());
		weekViewButton.setImage(Resource.checklistIcon);

		favoriteViewButton.setForeground(Color.CYAN);
		favoriteViewButton.setFont(buttonFont);
		southPanel.add(favoriteViewButton);
		favoriteViewButton.addClickOperater(new FavoriteActionOperator());
		favoriteViewButton.setImage(Resource.ratingIcon);
		favoriteViewButton.setGap(2);

		numLabel.setForeground(Color.YELLOW);
		numLabel.setFont(FontTools.getCustomFont(18));
		southPanel.add(numLabel);

		transPanel.setBounds(18, 12, 152, 52);
		lRadioButton.setBounds(30, 15, 120, 20);
		cRadioButton.setBounds(30, 38, 120, 20);
		dayBox.setBounds(190, 20, 110, 35);
		submitButton.setBounds(458, 18, 145, 40);
		weekViewButton.setBounds(630, 18, 165, 40);

		Rectangle r = ScreenTools.getCenterBounds(0.98f);
		if (MainApp.isFullScreenMode)
		{
			super.setBounds(r.x, r.y, r.width, r.height);
			setFullScreenMode(true);
		} else
		{
			setBounds(r.x, r.y, r.width, r.height);
		}
		initExtendMode(MainApp.isExtendMode);
		setDayAndMeal(0, 0);

		new Thread(() ->
		{
			RLafUtils.addSeparatorToSettingMenu();
			RLafUtils.addToSettingMenu(createSettingMenu());
			RLafUtils.addToSettingMenu(createUpdateMenu());
			RLafUtils.addToSettingMenu(new JMenuItem("关于软件"), (ActionEvent e) ->
			{
				if (aboutView == null)
					aboutView = new AboutDialog(this);
				aboutView.setVisible(true);
			});
			initNet();
		}).start();
	}

	private void initNet()
	{
		if (NetConfig.isServer())
		{
			server = ServerTools.getDefaultTools();
			server.enableUpdate().start();
			if (UpdateTools.isUpdateServer())
				UpdateTools.startUpdateServerTools();
			else if (autoUpdate)
				UpdateTools.startUpdateClientTools().autoCheckUpdate();
			netFunDialog = new AdminNetFunDialog(this, server);
		} else
		{
			client = ClientTools.getDefaultTools();
			client.connect();
			if (autoUpdate)
				client.autoCheckUpdate();
			sendUserInfo();
			client.addReConnectOperator((Object o) ->
			{
				sendUserInfo();
			});
		}
	}

	@Override
	public void setBounds(int x, int y, int frameWidth, int frameHeight)
	{
		if (container == null)
			return;
		if (frameWidth == getWidth() && frameHeight == getHeight())
		{
			super.setBounds(x, y, frameWidth, frameHeight);
			return;
		}
		updateSizeAndPosition(x, y, frameWidth, frameHeight);
	}

	static final int minLeftB = 6, minUpB = 5;
	private void updateSizeAndPosition(int x, int y, int frameWidth,
			int frameHeight)
	{
		int contentWidth = frameWidth;
		int contentHeight = frameHeight - 145;
		if (MainApp.isExtendMode)
		{
			tabbedPane.setBounds(8, 0, contentWidth - 16, contentHeight);
		} else
		{
			Insets insets = categoryPanels[0].getInsets();
			int ww = minLeftB * 2 + insets.left + insets.right;
			int w = (contentWidth - MainApp.columns.length * ww
					- (MainApp.columns.length - 1) * 5 - 20)
					/ MainApp.maxColumn;

			int ss = w / 15;
			ww = w - ss;
			int hh = ww * 8 / 9;
			int leftB = minLeftB + ss / 2;
			int xx = 10;
			contentHeight = CategoryPanel.getPreferredHeight(hh, ss, minUpB);
			int maxHeight = ScreenTools.getDefaultScreenSize().height;
			if (contentHeight + 145 > maxHeight)
				contentHeight = maxHeight - 145;
			for (int i = 0; i < categoryPanels.length; i++)
			{
				positionConfigers[i].updatePramater(ww, hh, ss, minUpB, leftB);
				w = categoryPanels[i].getPreferredWidth();
				categoryPanels[i].setBounds(xx, 0, w, contentHeight);
				xx += w + 5;
			}
			contentWidth = xx + 7;
		}

		southPanel.setBounds(0, contentHeight, contentWidth, 80);
		mealBox.setBounds(315, contentHeight + 20, 110, 35);
		if (cancelEditButton != null)
			cancelEditButton.setBounds(480, contentHeight + 20, 180, 40);
		if (setChooseNumButton != null)
			setChooseNumButton.setBounds(700, contentHeight + 22, 100, 36);
		if (setColumnButton != null)
			setColumnButton.setBounds(810, contentHeight + 22, 100, 36);
		favoriteViewButton.setBounds(805, 18, 178, 40);
		dataButton.setBounds(1000, 18, 135, 40);
		editButton.setBounds(1150, 18, 135, 40);
		netButton.setBounds(1300, 18, 135, 40);
		numLabel.setBounds(1450, 30, 180, 20);
		if (contentWidth < 1610)
		{
			contentHeight += 35;
			southPanel.setSize(contentWidth, 135);
			numLabel.setLocation(contentWidth - 185, 73);
			if (contentWidth < 1450)
				netButton.setLocation(contentWidth - 350, 63);
			if (contentWidth < 1300)
				editButton.setLocation(contentWidth - 500, 63);
			if (contentWidth < 1150)
				dataButton.setLocation(contentWidth - 650, 63);
			if (contentWidth < 990)
				favoriteViewButton.setLocation(contentWidth - 820, 63);
		}
		contentHeight += 80;
		int fw = frameWidth, fh = frameHeight, yy = 0;
		int height = contentHeight + 30;
		if (MainApp.isFullScreenMode)
		{
			if (contentWidth > fw)
				fw = contentWidth;
			if (height > fh)
				fh = height;
			yy = Math.min((fh - height + 10) / 2, 20);
		} else
		{
			fw = contentWidth;
			fh = height;
		}
		container.setBounds((fw - contentWidth) / 2, yy, contentWidth,
				contentHeight);
		super.setBounds(x - (fw - frameWidth) / 2, y - (fh - frameHeight) / 2,
				fw, fh);
	}

	public int getTotalChooseNumber()
	{
		int n = 0;
		for (int i = 0; i < categoryPanels.length; i++)
			n = n + categoryPanels[i].getChooseNumber();
		return n;
	}

	public RecommendData getRecommendData()
	{
		return recommendData;
	}

	public void setRecommendData(RecommendData recommendData)
	{
		this.recommendData = recommendData;
	}

	public JTabbedPane getTabbedPane()
	{
		return tabbedPane;
	}

	public boolean isSelectBreakfast()
	{
		return chooseMeal == 0;
	}

	public boolean writeCountDataToFile(File f)
	{
		if (f == null)
			return false;
		try (DataOutputStream dos = new DataOutputStream(
				new FileOutputStream(f)))
		{
			for (int i = 0; i < categoryDatas.length; i++)
			{
				categoryDatas[i].writeCountData(dos);
			}
			dos.writeInt(submitNum);
			dos.close();
			return true;
		} catch (Exception e)
		{
			e.printStackTrace();
			return false;
		}
	}

	public boolean readCountDataFromFile(File f)
	{
		if (f == null || !f.isFile())
			return false;
		try (DataInputStream dis = new DataInputStream(new FileInputStream(f)))
		{
			for (int i = 0; i < categoryDatas.length; i++)
			{
				categoryDatas[i].readCountData(dis);
			}
			submitNum = dis.readInt();
			dis.close();
		} catch (Exception e)
		{
			ROptionPane.showMessageDialog(this, "数据不匹配！", "提示!");
			e.printStackTrace();
			return false;
		}
		numLabel.setText(str + submitNum);
		recommendData.caculateRecommendDataInThread();
		return true;
	}

	public boolean readCombineCountDataFromFile(File f)
	{
		if (f == null || !f.isFile())
			return false;
		try (DataInputStream dis = new DataInputStream(new FileInputStream(f)))
		{
			for (int i = 0; i < categoryDatas.length; i++)
			{
				categoryDatas[i].readAndCombineCountData(dis);
			}
			submitNum += dis.readInt();
			dis.close();
		} catch (Exception e)
		{
			ROptionPane.showMessageDialog(this, "数据不匹配！", "提示!");
			e.printStackTrace();
			return false;
		}
		numLabel.setText(str + submitNum);
		recommendData.caculateRecommendDataInThread();
		return true;
	}

	public void clearData()
	{
		for (int i = 0; i < categoryDatas.length; i++)
			categoryDatas[i].clearData();
		submitNum = 0;
		numLabel.setText(str + submitNum);
		recommendData.clearData();
	}

	public void setDayAndMeal(int d, int m)
	{
		chooseDay = d;
		chooseMeal = m;
		dayBox.setSelectedIndex(d);
		mealBox.setSelectedIndex(m);
		if (m == 0)
			for (int i = 0; i < categoryPanels.length; i++)
				categoryPanels[i].chooseBreakfast();
		else if (m == 1 || m == 2)
			for (int i = 0; i < categoryPanels.length; i++)
				categoryPanels[i].chooseOther();
	}

	public void setEditable(boolean editable)
	{
		if (this.editable == editable)
			return;
		this.editable = editable;
		if (editable)
		{
			if (cancelEditButton == null)
			{
				cancelEditButton = new TransRichButton("退出菜单编辑");
				cancelEditButton.setForeground(new Color(255, 50, 50));
				cancelEditButton.setFont(FontTools.getCustomFont(20));
				cancelEditButton.setImage(Resource.cancelIcon);
				cancelEditButton.addActionListener((ActionEvent e) ->
				{
					setEditable(false);
				});
				cancelEditButton.setBounds(480, mealBox.getY(), 180, 40);
			}
			if (setChooseNumButton == null)
			{
				setChooseNumButton = new TransRichButton("设置选择数量");
				setChooseNumButton.setForeground(Color.green);
				setChooseNumButton.setFont(FontTools.getCustomFont(14));
				setChooseNumButton.addActionListener((ActionEvent e) ->
				{
					showSetNumDialog(this);
				});
				setChooseNumButton.setBounds(700, mealBox.getY() + 2, 100, 36);
			}
			if (setColumnButton == null)
			{
				setColumnButton = new TransRichButton("设置菜单列数");
				setColumnButton.setForeground(Color.green);
				setColumnButton.setFont(FontTools.getCustomFont(14));
				setColumnButton.addActionListener((ActionEvent e) ->
				{
					showSetColDialog(this);
				});
				setColumnButton.setBounds(810, mealBox.getY() + 2, 100, 36);
			}
			container.remove(southPanel);
			container.add(cancelEditButton);
			container.add(setChooseNumButton);
			container.add(setColumnButton);
		} else
		{
			container.remove(cancelEditButton);
			container.remove(setChooseNumButton);
			container.remove(setColumnButton);
			container.add(southPanel);
		}
		updateTitle();
		for (int i = 0; i < categoryPanels.length; i++)
			categoryPanels[i].setEditable(editable);
		validate();
		repaint();
	}

	private void initExtendMode(boolean b)
	{
		if (b)
		{
			for (CategoryPanel panel : categoryPanels)
			{
				panel.setExtendMode(b);
				container.remove(panel);
				tabbedPane.add(panel, " " + panel.getCategoryName() + " ");
			}
			container.add(tabbedPane);
		} else
		{
			container.remove(tabbedPane);
			tabbedPane.removeAll();
			for (CategoryPanel panel : categoryPanels)
			{
				panel.setExtendMode(b);
				container.add(panel);
			}
		}
	}

	public void setExtendMode(boolean b)
	{
		initExtendMode(b);
		updateSizeAndPosition(getX(), getY(), getWidth(), getHeight());
		revalidate();
		repaint();
	}

	public void sendUserInfo()
	{
		if (client != null && client.isConnected())
		{
			CommandPacket commandPacket = new CommandPacket(
					Command.C.sendUserInfo);
			commandPacket.setStringData("用户：" + MainApp.userName + "   地址："
					+ client.getClientDetail() + "  版本号："
					+ AppConfig.appVersion);
			client.sendCommand(commandPacket);
		}
	}

	public void updateTitle()
	{
		String title = MainApp.appName;
		if (NetConfig.isServer())
			title += "（管理员）";
		if (editable)
			title += "— 菜单编辑";
		setTitle(title);
	}

	private class SubmitActionListener implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e)
		{
			if (getTotalChooseNumber() > 0)
			{
				for (int i = 0; i < categoryPanels.length; i++)
				{
					categoryPanels[i].count(chooseDay, chooseMeal);
					categoryPanels[i].clearAllChoose();
				}
				recommendData.caculateRecommendMealDataInThread(chooseDay);
				submitNum++;
				numLabel.setText(str + submitNum);
				JOptionPane.showMessageDialog(MainFrame.this,
						"提交成功！当前已统计" + submitNum + "次。", "提交选择",
						JOptionPane.OK_OPTION, Resource.submitIcon);
			} else
				ROptionPane.showMessageDialog(MainFrame.this, "没有选择，请选择后再提交！",
						"提交选择");
		}
	}

	private class DataActionListener implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e)
		{
			if (dataPopupMenu == null)
				dataPopupMenu = createDataPopMenu();
			// System.out.println(dataPopupMenu.getLayout());
			dataPopupMenu.show(dataButton, 0, -dataPopHeight);
		}
	}

	private class EditActionListener implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e)
		{
			OneWeekView oneWeekView = MainApp.getOneWeekView();
			oneWeekView.setEditable(true);
			oneWeekView.setTitle("食 谱 编 辑");
			oneWeekView.showView();
		}
	}

	private class NetButtonListener implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e)
		{
			if (netFunDialog == null)
			{
				if (NetConfig.isServer())
					netFunDialog = new AdminNetFunDialog(MainFrame.this,
							server);
				else
					netFunDialog = new NetFunDialog(MainFrame.this, client);
			}
			// netFunDialog.setVisible(true);
			WindowTools.showWindowFromBorderToCenter(netFunDialog, 30,
					Direction.UP);
		}
	}

	private class DayBoxActionListener implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e)
		{
			chooseDay = dayBox.getSelectedIndex();
		}
	}

	private class MealBoxActionListener implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e)
		{
			int index = mealBox.getSelectedIndex();
			if (index == 0 && chooseMeal != 0)
				for (int i = 0; i < categoryPanels.length; i++)
					categoryPanels[i].chooseBreakfast();
			else if ((index == 1 || index == 2) && chooseMeal == 0)
				for (int i = 0; i < categoryPanels.length; i++)
					categoryPanels[i].chooseOther();
			chooseMeal = index;
		}
	}

	private class FavoriteActionOperator implements Operator
	{
		@Override
		public void operate(Object o)
		{
			WindowTools.showWindowFromBorderToCenter(MainApp.getFavoriteView(),
					Direction.UP);
		}
	}

	private class WeekActionOperator implements Operator
	{
		@Override
		public void operate(Object o)
		{
			OneWeekView oneWeekView = MainApp.getOneWeekView();
			oneWeekView.setEditable(false);
			oneWeekView.setToRecommend(recommendData.getFavoriteDatas());
			oneWeekView.setTitle("一 周 推 荐 食 谱");
			oneWeekView.showView();
		}
	}

	private JMenu createSettingMenu()
	{
		JMenu settingMenu = new JMenu("软件设置");

		JMenuItem modeSetItem = new JMenuItem(
				MainApp.isExtendMode ? "完整模式" : "扩大模式");
		modeSetItem.addActionListener((ActionEvent e) ->
		{
			if (MainApp.isExtendMode)
			{
				MainApp.setExtendMode(false);
				setExtendMode(false);
				modeSetItem.setText("扩大模式");
			} else
			{
				MainApp.setExtendMode(true);
				setExtendMode(true);
				modeSetItem.setText("完整模式");
			}
		});
		JMenuItem fullScreenSetItem = new JMenuItem(
				MainApp.isFullScreenMode ? "退出全屏" : "进入全屏");
		fullScreenSetItem.addActionListener((ActionEvent e) ->
		{
			if (MainApp.isFullScreenMode)
			{
				MainApp.setFullScreenMode(false);
				setFullScreenMode(false);
				fullScreenSetItem.setText("进入全屏");
			} else
			{
				MainApp.setFullScreenMode(true);
				setFullScreenMode(true);
				fullScreenSetItem.setText("退出全屏");
			}
		});
		JMenuItem editItem = new JMenuItem("菜单编辑");
		editItem.addActionListener((ActionEvent e) ->
		{
			setEditable(true);
		});
		JMenuItem advanceSetItem = new JMenuItem("高级设置");
		advanceSetItem.addActionListener((ActionEvent e) ->
		{
			if (softSettingDialog == null)
				softSettingDialog = createSoftSettingDialog();
			softSettingDialog.setVisible(true);
		});

		settingMenu.add(modeSetItem);
		settingMenu.add(fullScreenSetItem);
		settingMenu.add(editItem);
		settingMenu.add(advanceSetItem);
		return settingMenu;
	}

	private JMenu createUpdateMenu()
	{
		JMenu updateMenu = new JMenu("软件更新");
		JCheckBoxMenuItem autoUpateItem = new JCheckBoxMenuItem("自动更新",
				autoUpdate);
		autoUpateItem.addActionListener((ActionEvent e) ->
		{
			new Thread(() ->
			{
				synchronized (autoUpateItem)
				{
					autoUpdate = autoUpateItem.isSelected();
					SettingTools.putDefaultSettingData("autoUpdate",
							autoUpdate);
					if (NetConfig.isServer())
					{
						if (!UpdateTools.isUpdateServer())
							if (autoUpdate)
								UpdateTools.startUpdateClientTools()
										.autoCheckUpdate();
							else
								UpdateTools.getUpdateClientTools().stop();
					} else if (client != null)
						client.setAutoUpdate(autoUpdate);
				}
			}).start();
		});
		JMenuItem checkUpdateItem = new JMenuItem("检查更新");
		checkUpdateItem.addActionListener((ActionEvent e) ->
		{
			new Thread(() ->
			{
				synchronized (checkUpdateItem)
				{
					checkUpdate();
				}
			}).start();
		});
		updateMenu.add(autoUpateItem);
		updateMenu.add(checkUpdateItem);
		return updateMenu;
	}

	void checkUpdate()
	{
		if (NetConfig.isClient())
		{
			if (client != null)
				client.manualCheckUpdate();
		} else if (!UpdateTools.isUpdateServer())
		{
			UpdateTools.startUpdateClientTools().manualCheckUpdate();
			try
			{
				Thread.sleep(2000);
			} catch (InterruptedException e1)
			{
				e1.printStackTrace();
			}
			ClientTools updateClient = UpdateTools.getUpdateClientTools();
			if (!updateClient.isAutoUpdate())
				updateClient.stop();
		}
	}

	RFileChooser dataChooser = null;

	private JPopupMenu createDataPopMenu()
	{
		JPopupMenu popup = new JPopupMenu();
		JMenuItem openLast = new JMenuItem("恢复上次数据");
		JMenuItem clearCurrent = new JMenuItem("清空当前数据");
		JMenuItem combine = new JMenuItem("合并统计数据");
		JMenuItem open = new JMenuItem("打开统计数据");
		JMenuItem save = new JMenuItem("保存统计数据");
		JMenuItem reset = new JMenuItem("重新初始化");
		// reset.setHorizontalAlignment(SwingConstants.CENTER);

		Font font = FontTools.getBigFont();
		openLast.setFont(font);
		clearCurrent.setFont(font);
		combine.setFont(font);
		open.setFont(font);
		save.setFont(font);
		reset.setFont(font);
		popup.add(openLast);
		popup.add(clearCurrent);
		popup.add(combine);
		popup.add(open);
		popup.add(save);
		popup.add(reset);
		dataPopHeight = popup.getPreferredSize().height;
		openLast.addActionListener((ActionEvent e) ->
		{
			boolean ok = readCountDataFromFile(MainApp.getLastDataFile());
			if (ok)
				HintWindow.showHint("已恢复上次统计数据", MainFrame.this);
		});
		clearCurrent.addActionListener((ActionEvent e) ->
		{
			clearData();
			HintWindow.showHint("数据已清空", MainFrame.this);
		});
		combine.addActionListener((ActionEvent e) ->
		{
			if (dataChooser == null)
				dataChooser = new RFileChooser(MainApp.getCountDataFolder(),
						"data", null);
			dataChooser.setDialogTitle("合并统计数据——选择data文件");
			boolean ok = readCombineCountDataFromFile(
					dataChooser.openAndGetOpenFile(MainFrame.this));
			if (ok)
				HintWindow.showHint("数据合并完成", MainFrame.this);
		});
		open.addActionListener((ActionEvent e) ->
		{
			if (dataChooser == null)
				dataChooser = new RFileChooser(MainApp.getCountDataFolder(),
						"data", null);
			dataChooser.setDialogTitle("打开统计数据——选择data文件");
			boolean ok = readCountDataFromFile(
					dataChooser.openAndGetOpenFile(MainFrame.this));
			if (ok)
				HintWindow.showHint("已打开新数据", MainFrame.this);
		});
		save.addActionListener((ActionEvent e) ->
		{
			if (dataChooser == null)
				dataChooser = new RFileChooser(MainApp.getCountDataFolder(),
						"data", null);
			dataChooser.setDialogTitle("保存统计数据——选择data文件");
			boolean ok = writeCountDataToFile(
					dataChooser.openAndGetSaveFile(MainFrame.this));
			if (ok)
				HintWindow.showHint("数据保存成功", MainFrame.this);
		});
		reset.addActionListener((ActionEvent e) ->
		{
			MainApp.resetData();
		});
		return popup;
	}

	private JDialog createSoftSettingDialog()
	{
		final RDialog dialog = new RDialog(MainFrame.this);
		dialog.setOptionStyle(150, 0.9f);
		dialog.setTitle("高级设置");
		dialog.setTitleHeight(30);
		dialog.setTitleColor(Color.yellow);
		dialog.setWindowSymbol(Resource.settingIcon);
		dialog.setSection(10);
		dialog.setSize(300, 230);
		dialog.setLocationRelativeTo(null);
		dialog.getContentPane().setLayout(new GridLayout(2, 0, 8, 8));
		RButton setNum = new RButton("选择数量设置");
		RButton setCol = new RButton("菜单列数设置");
		RButton setNet = new RButton("食谱设置");
		RButton setMore = new RButton("更多设置");
		RButton[] buttons = {setNum, setCol, setNet, setMore};

		for (int i = 0; i < buttons.length; i++)
		{
			buttons[i].setFont(FontTools.getCustomFont(13));
			dialog.add(buttons[i]);
			buttons[i].setRound(25);
		}
		dialog.addClosingOperater((Object o) ->
		{
			if (setNumDialog != null)
				setNumDialog.dispose();
			if (setColDialog != null)
				setColDialog.dispose();
			if (setRecipeDialog != null)
				setRecipeDialog.dispose();
			if (setMoreDialog != null)
				setMoreDialog.dispose();
		});
		setNum.addActionListener((ActionEvent e) ->
		{
			showSetNumDialog(dialog);
		});
		setCol.addActionListener((ActionEvent e) ->
		{
			showSetColDialog(dialog);
		});
		setNet.addActionListener((ActionEvent e) ->
		{
			if (NetConfig.isClient() && client != null)
				showSetRecipeDialog(dialog);
		});
		setMore.addActionListener((ActionEvent e) ->
		{
			showSetMoreDialog(dialog);
		});

		//		switchFullScreen.addActionListener((ActionEvent e) ->
		//		{
		//			dialog.dispose();
		//			if (MainApp.isFullScreenMode)
		//			{
		//				MainApp.setFullScreenMode(false);
		//				setFullScreenMode(false);
		//				switchFullScreen.setText("进入全屏");
		//			} else
		//			{
		//				MainApp.setFullScreenMode(true);
		//				setFullScreenMode(true);
		//				switchFullScreen.setText("退出全屏");
		//			}
		//		});
		return dialog;
	}

	private void showSetNumDialog(Window window)
	{
		if (setNumDialog == null)
			setNumDialog = new SetNumDialog(window);
		if (setNumDialog.isVisible())
			return;
		setNumDialog.updateData();
		if (setColDialog != null && setColDialog.isVisible())
			WindowTools.setHorizonLocation(setNumDialog, setColDialog);
		else
		{
			setNumDialog.setLocationRelativeTo(window);
		}
		setNumDialog.setVisible(true);
	}

	private void showSetColDialog(Window window)
	{
		if (setColDialog == null)
			setColDialog = new SetColDialog(window);
		if (setColDialog.isVisible())
			return;
		setColDialog.updateData();
		if (setNumDialog != null && setNumDialog.isVisible())
			WindowTools.setHorizonLocation(setColDialog, setNumDialog);
		else
		{
			setColDialog.setLocationRelativeTo(window);
		}
		setColDialog.setVisible(true);
	}

	private void showSetRecipeDialog(JDialog dialog)
	{
		if (setRecipeDialog == null)
			setRecipeDialog = new SetRecipeDialog(dialog, this);
		setRecipeDialog.setLocationRelativeTo(dialog);
		setRecipeDialog.setVisible(true);

		//		if (setNetDialog == null)
		//			setNetDialog = new SetNetDialog(client, dialog);
		//		setNetDialog.updateContent();
		//		setNetDialog.setLocationRelativeTo(dialog);
		//		setNetDialog.setVisible(true);
	}

	private void showSetMoreDialog(JDialog dialog)
	{
		if (setMoreDialog == null)
			setMoreDialog = new SetMoreDialog(dialog, this);
		if (setMoreDialog.isVisible())
			return;
		setMoreDialog.updateContent();
		setMoreDialog.setLocationRelativeTo(dialog);
		setMoreDialog.setVisible(true);
	}

	private class RadioButtonActionListener implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e)
		{
			if (lRadioButton.isSelected())
				clickToLager = true;
			else if (cRadioButton.isSelected())
				clickToLager = false;
			SettingTools.putDefaultSettingData("clickToLager", clickToLager);
		}
	}

	private class CloseOperator implements Operator
	{
		@Override
		public void operate(Object o)
		{
			File forder = MainApp.getLastDataFile().getParentFile();
			boolean b = forder.exists();
			writeCountDataToFile(
					FileTools.createFile(MainApp.getLastDataFile()));
			if (!b)
				FileTools.setToHidden(forder);
		}
	}
}
